using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using System.Configuration;

namespace WiiFlipChart
{
    public partial class DrawBoard : Form
    {


        private Timer PulsingPointTimer;
        private int i = 0;


        private int DrawFieldPositionX=0;
        private int DrawFieldPositionY=0;
        
       

        //Bitmaps for the pulsing Point
        private Bitmap pulsinPointIcon1 = null;
        private Bitmap pulsinPointIcon2 = null;



        private Bitmap StrokeWidthPanelBmp;
        private Graphics grfxStrokeWidthPanel;
        private int StrokeWidthPanelPosX;
        private int StrokeWidthPanelPosY;


        private Bitmap PageInfoPanel;
      //########################################
       
        private Point lastPoint;
        private Point newPoint;
        private Pen myPen = new Pen(Color.Black);






        static readonly DrawBoard instance = new DrawBoard();

        public static DrawBoard Instance
        {
            get
            {
                return instance;
            }
        }







        /// <summary>
        /// instantiate the Board
        /// Subscribe Eventhandler for ColorChange 
        /// Subscribe Eventhandler for StrokewithChange
        /// Subscribe Eventhandler Button A Pressed on WiiMOTE
        /// Subscribe Eventhandler CurrentPageChanged  to show the number and page on the form
        /// init the Class Contoller
        /// init all panels on the form
        /// </summary>
        public DrawBoard()
        {
            InitializeComponent();

            this.ResizeRedraw = true;

            Controller cont = Controller.Instance;

            Controller.Instance.Init();

            DrawFieldPositionX = Controller.Instance.getDrawFieldPositionX();
            DrawFieldPositionY = Controller.Instance.getDrawFieldPositionY();

            //Set the Location and Size of the Form
            this.Location = new Point(0, 0);
            
            this.Size = new System.Drawing.Size(Controller.Instance.getBoardWindowSizeX(), 
                                                Controller.Instance.getBoardWindowSizeY());


            //Subscribe Eventhandler for ColorChange 
            ColorControl.Instance.ColorChanged += new EventHandler(ColorChanged);

            //Subscribe Eventhandler for StrokewithChange
            StrokeWidthControl.Instance.StrokeWidthChanged += new EventHandler(StrokeWidthChanged);

            //Subscribe Eventhandler Button A Pressed on WiiMOTE and drawing is possible
            Controller.Instance.ButtonAChanged += new EventHandler(DrawFree);


            //Subscribe Eventhandler CurrentDrawPointChanged from WiiMote
            Controller.Instance.CurrentDrawCursorPointChanged += new EventHandler(CurrentDrawCursorPointChanged);

            //Subscribe Eventhandler CurrentPageChanged  to show the number on the form
            PageControl.Instance.CurrentPageChanged += new EventHandler(CurrentPageChanged);


            InitPulsingPointIcon();
            
            InitPulsingPointTimer();

            InitColorPanel();

            InitStrokeWidthPanel(); DrawStrokeIndicator(); DrawStrokeWidthPanel();

            InitPageInfoPanel();

           
         


        }

        
        /// <summary>
        /// Display Current Pagenumber on the Form
        /// </summary>

        private void InitPageInfoPanel()
        {
            PageInfoPanel = new Bitmap(200, 60);
            Graphics g = Graphics.FromImage(PageInfoPanel);
            g.DrawString("Page", new Font("Comic Sans MS", 14), new SolidBrush(Color.Black), 10, 0);

            g.DrawString(">>  1  <<", new Font("Comic Sans MS", 14), new SolidBrush(Color.Black), 0, 30);

            g.Dispose();


        }







        private void InitStrokeWidthPanel()
        {

            StrokeWidthPanelBmp = new Bitmap(145, 175);
            StrokeWidthPanelPosX = Controller.Instance.getBoardWindowSizeX() - 200;
            StrokeWidthPanelPosY = Controller.Instance.getBoardWindowSizeY() - 257;
            
            grfxStrokeWidthPanel = Graphics.FromImage(StrokeWidthPanelBmp);

            grfxStrokeWidthPanel.FillRectangle(new SolidBrush(Color.FromArgb(229, 229, 229)) , 0, 0, 145, 175);
            
            //Bring the graphics panel to form
            Graphics g = this.CreateGraphics();
            g.DrawImage(StrokeWidthPanelBmp, StrokeWidthPanelPosX, StrokeWidthPanelPosY);
            g.Dispose();

        }

        private void DrawStrokeWidthPanel()
        {

            grfxStrokeWidthPanel = Graphics.FromImage(StrokeWidthPanelBmp);

            grfxStrokeWidthPanel.DrawString("Stroke Width", new Font("Comic Sans MS", 10,FontStyle.Bold), new SolidBrush(Color.Black), 25, 10);

            int barlength = 70;
            int x = 40;

            //Border
            grfxStrokeWidthPanel.DrawRectangle(new Pen(Color.Black, 2), 1, 1, 142, 169);

            
            // Stroke rectangles
            for (int i = 0; i <= 4; i++)
            {
                grfxStrokeWidthPanel.FillRectangle(new SolidBrush(Color.Black), x, 35 + i * 20 + 9 - i, barlength, i + 1);
            }

            
            //Bring the graphics panel to form
            Graphics g = this.CreateGraphics();
            g.DrawImage(StrokeWidthPanelBmp, StrokeWidthPanelPosX, StrokeWidthPanelPosY);
            g.Dispose();      


        }




        private void InitColorPanel()
        {


            this.panelcurrentcolor.BackColor = Color.FromName(ColorControl.Instance.getarrColor(0));

            this.panel1.BackColor = Color.FromName(ColorControl.Instance.getarrColor(0));
           
            this.panel2.BackColor = Color.FromName(ColorControl.Instance.getarrColor(1));
            this.panel3.BackColor = Color.FromName(ColorControl.Instance.getarrColor(2));
            this.panel4.BackColor = Color.FromName(ColorControl.Instance.getarrColor(3));
            this.panel5.BackColor = Color.FromName(ColorControl.Instance.getarrColor(4));
            this.panel6.BackColor = Color.FromName(ColorControl.Instance.getarrColor(5));
            this.panel7.BackColor = Color.FromName(ColorControl.Instance.getarrColor(6));
            this.panel8.BackColor = Color.FromName(ColorControl.Instance.getarrColor(7));
            this.panel9.BackColor = Color.FromName(ColorControl.Instance.getarrColor(8));
            this.panel10.BackColor = Color.FromName(ColorControl.Instance.getarrColor(9));

        
        }

        private void InitPulsingPointTimer()
        {
           PulsingPointTimer = new Timer();
           PulsingPointTimer.Interval = 300;
           PulsingPointTimer.Start();
           PulsingPointTimer.Tick += new EventHandler(ChangePulsingPoint);
        }

        /// <summary>
        /// Creates both icons for the pulsing mousepointer
        /// </summary>
        private void InitPulsingPointIcon()
        { 
            
            pulsinPointIcon1 = new Bitmap(10, 10);
            Graphics u = Graphics.FromImage(pulsinPointIcon1);
            u.DrawEllipse(new Pen(Brushes.Red), 3, 3, 3, 3);

            pulsinPointIcon2 = new Bitmap(10, 10);
            Graphics g = Graphics.FromImage(pulsinPointIcon2);
            g.DrawEllipse(new Pen(Brushes.Red), 0, 0, 9, 9);

        }

        

       


        /// <summary>
        /// Draw  the GrafikstrokePanel
        /// Draw PageInfoPanel
        /// If Form repaint load the picture to the form
        /// Draw the Border for Colorpanel
        /// This is the Border for Colorpanel
        /// </summary>

        private void DrawBoard_Paint(object sender, PaintEventArgs e)
        {


            //Draw boarder around the DrawField
            e.Graphics.DrawRectangle(new Pen(Color.Black,2), DrawFieldPositionX - 1,
                DrawFieldPositionY - 1, Controller.Instance.getDrawFieldSizeX() + 2, 
                                        Controller.Instance.getDrawFieldSizeY() + 2);
            
  
            
            //Draw PageInfoPanel
            e.Graphics.DrawImage(PageInfoPanel, DrawFieldPositionX + 310, DrawFieldPositionY -70);


            //Draw  the GrafikstrokePanel
            e.Graphics.DrawImage(StrokeWidthPanelBmp, StrokeWidthPanelPosX, StrokeWidthPanelPosY);


             //if the form will be repaint load the picture to form
           e.Graphics.DrawImage(PageControl.Instance.getCurrentPage(),DrawFieldPositionX,DrawFieldPositionY);


            //This is the Border for Colorpanel
           e.Graphics.DrawRectangle(new Pen(Color.Black, 2), this.Size.Width - 200, DrawFieldPositionY+110, 142, 300);




        
        }

        
        /// <summary>
        /// if form was closed disconnect from wiimote
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DrawBoard_FormClosed(object sender, FormClosedEventArgs e)
        {
           
            WiiMoteDetection.Instance.wm.Disconnect();
        }



        /// <summary>
        /// Draw the indicator rectangel of the current strokewidth
        /// </summary>
        private void DrawStrokeIndicator()
        {
            int barlength = 70;
            int x = 40;

            grfxStrokeWidthPanel = Graphics.FromImage(StrokeWidthPanelBmp);

            grfxStrokeWidthPanel.FillRectangle(new SolidBrush(Color.White), x - 5, 35 +
                (StrokeWidthControl.Instance.getcurrentstrokewidth() - 1) * 20, barlength + 15, 18);


            Graphics g = this.CreateGraphics();
            g.DrawImage(StrokeWidthPanelBmp, StrokeWidthPanelPosX, StrokeWidthPanelPosY);
            g.Dispose();


        }



        //EVENT BASED Methods
        
        /// <summary>
        /// Change Color of Current color Panel
        /// </summary>

        protected void ColorChanged(Object objSender, EventArgs e)
        {
            this.panelcurrentcolor.BackColor = ColorControl.Instance.getcurrentColor();
        }



        /// <summary>   
        /// Change Strokewidth Panel
        /// </summary>
        protected void StrokeWidthChanged(Object objSender, EventArgs e)
        {

            InitStrokeWidthPanel();

            DrawStrokeIndicator();

            DrawStrokeWidthPanel();


        }



        /// <summary>   
        /// Change lastpoint with current DrawCursorPoint
        /// </summary>
         
        protected void CurrentDrawCursorPointChanged(Object objSender, EventArgs e)
        {
            this.lastPoint = Controller.Instance.getCurrentDrawCursorPoint();
        }



        /// <summary>   
        /// Change pulsing point icon alternately
        /// </summary>
        private void ChangePulsingPoint(Object objSender, EventArgs e)
        {

            if (Controller.Instance.getCursorInDrawField() == true)
            {
                if (i == 1)
                {
                    IntPtr ptr = pulsinPointIcon1.GetHicon();
                    Cursor c = new Cursor(ptr);
                    this.Cursor = c;
                    i = 0;
                }

                else
                {
                    IntPtr ptr = pulsinPointIcon2.GetHicon();
                    Cursor c = new Cursor(ptr);
                    this.Cursor = c;
                    i = 1;
                }
            }
            else { this.Cursor = Cursors.Default; }
        }


        /// <summary>   
        /// Draw in then Drawfield
        /// </summary>
        protected void DrawFree(Object objSender, EventArgs e)
        {

            myPen.Color = ColorControl.Instance.getcurrentColor();
            myPen.Width = StrokeWidthControl.Instance.getcurrentstrokewidth();
            newPoint = Controller.Instance.getCurrentDrawCursorPoint();


            //Draw this on the Panel
            Graphics g = this.CreateGraphics();
            g.DrawLine(myPen, lastPoint, newPoint);
            g.Dispose();

            lastPoint = newPoint;


        }


        /// <summary>   
        /// Draw the picture and the picturenumber to the form if there is an Change of the chart
        /// </summary>
        protected void CurrentPageChanged(Object objSender, EventArgs e)
        {

            PageInfoPanel = new Bitmap(200, 60);
            Graphics g = Graphics.FromImage(PageInfoPanel);
            
            g.DrawString("Page", new Font("Comic Sans MS", 14), new SolidBrush(Color.Black), 10, 0);

            g.DrawString(">>  "+ PageControl.Instance.getCurrentPageNumer()+ "  <<", 
                new Font("Comic Sans MS", 14), new SolidBrush(Color.Black),0, 30);
            
            g.Dispose();

        }

      








  

       
    }
}